﻿using D3StatsClient.Model;
using D3StatsClient.ServiceModel;
using D3StatsClient.View;
using D3StatsClient.ViewModel;
using DBLootTrackerPlugin.ServiceModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Threading;

namespace D3StatsClient.Commands
{
    public class StartRecordingSession : CommandBase
    {
        public override bool CanExecute(object parameter)
        {
            var vm = ViewModelManager<MainWindowViewModel>.ViewModel;

            if ((Properties.Settings.Default.EnableMultiProcessSupport 
                && vm.IsSessionLoaded) 
                && !vm.IsRecording
                && !vm.IsContinuedSession)
            {
                return true;
            }

            if (vm.IsRecording || !vm.IsSessionLoaded)
            {
                return false;
            }

            if (vm.IsContinuedSession)
            {
                return false;
            }

            if (this.IsTrackerServiceAvailable())
            {
                vm.Status = "Loot Tracker service is available for connection...";
                return true;
            }
            else
            {
                vm.Status = "Loot Tracker service is not available for connection...";
            }

            return false;
        }

        private bool IsTrackerServiceAvailable()
        {
            DuplexChannelFactory<ILootTrackerDataService> trackerServiceFactory = null;

            try
            {
                LootTrackerDataServiceCallbacks myCallbacks = new LootTrackerDataServiceCallbacks();
                var vm = ViewModelManager<MainWindowViewModel>.ViewModel;

                trackerServiceFactory =
                   new DuplexChannelFactory<ILootTrackerDataService>(
                      myCallbacks,
                      new NetNamedPipeBinding(),
                      new EndpointAddress(
                         "net.pipe://localhost/" + Properties.Settings.Default.TrackerServiceProviderName));

                trackerServiceFactory.Endpoint.Binding.SendTimeout = TimeSpan.FromSeconds(.5);
                ILootTrackerDataService proxy = trackerServiceFactory.CreateChannel();
                return proxy.IsAlive();
            }
            catch (Exception)
            {
                return false;
            }
            finally
            {
                if (trackerServiceFactory != null)
                {
                    try
                    {
                        trackerServiceFactory.Close();
                    }
                    catch { trackerServiceFactory.Abort(); }
                }
            }
        }

        private bool SuscribeToTrackerService()
        {
            try
            {
                LootTrackerDataServiceCallbacks myCallbacks = new LootTrackerDataServiceCallbacks();
                var vm = ViewModelManager<MainWindowViewModel>.ViewModel;

                vm.trackerServiceChanel = new DuplexChannelFactory<ILootTrackerDataService>(
                      myCallbacks,
                      new NetNamedPipeBinding(),
                      new EndpointAddress(
                         "net.pipe://localhost/" + Properties.Settings.Default.TrackerServiceProviderName));

                vm._trackerService = vm.trackerServiceChanel.CreateChannel();

                return vm._trackerService.Subscribe();
            }
            catch(Exception)
            {
                return false;
            }
        }

        public override void Execute(object parameter)
        {
            var vm = ViewModelManager<MainWindowViewModel>.ViewModel;

            //Will start monitoring plugin notifications
            bool result = this.SuscribeToTrackerService();

            if (result)
            {

                //Start recording data.
                vm.SetStatus(true);
                vm.IsRecording = true;
                vm.IsSessionLoaded = true;

                vm.sw = new Stopwatch();
                vm.sw.Start();

                vm.Server = D3StatsUtility.GetGameInstanceServerIp();

                DispatcherTimer timer = new DispatcherTimer(new TimeSpan(0, 0, 0, 1), DispatcherPriority.Normal, delegate
                {
                    if (vm.IsRecording)
                    {
                        var provider = vm.provider as XMLStatsProvider;
                        TimeSpan previoustime = TimeSpan.Zero;

                        if (provider.XMLData.Element("items").Attribute("played") != null)
                        {
                            previoustime = TimeSpan.Parse(provider.XMLData.Element("items").Attribute("played").Value);
                        }

                        vm.SessionTime = previoustime == TimeSpan.Zero ? vm.GetTimeSpanFormattedString(vm.sw.Elapsed) : vm.GetTimeSpanFormattedString((vm.sw.Elapsed + previoustime));
                    }

                }, this._currentDispatcher);

                vm.Status = "Currently monitoring item drops...";
            }

            else
            {
                vm.Status = "Could not connect to tracker service, make sure the Loot Tracker Plugin is enabled and started.";
            }
        }

        
    }
}
